package com.kudian.restful.service;

import com.kudian.common.exception.ApplicationException;
import com.kudian.common.persistence.HibernateDao;
import com.kudian.common.persistence.ResultObj;
import com.kudian.common.service.BaseService;
import com.kudian.common.utils.*;
import com.kudian.restful.dao.*;
import com.kudian.restful.entity.*;
import com.kudian.restful.vo.order.*;
import com.kudian.restful.vo.userbonus.BonusItemVO;
import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.*;

/**
 * Created by Administrator on 2016/4/18.
 * 创建订单信息
 */
@Service
@Transactional(readOnly = true)
public class OrderService extends BaseService<OrderInfo, Integer> {
    private static final Logger logger = Logger.getLogger(OrderService.class);

    @Autowired
    private OrderInfoDao orderInfoDao;

    @Autowired
    private LoginSessionDao loginSessionDao;

    @Autowired
    private SellerDao sellerDao;

    @Autowired
    private OrderSellerDao orderSellerDao;

    @Autowired
    private SequenceDao sequenceDao;

    @Autowired
    private OrderGoodsDao orderGoodsDao;

    @Autowired
    private GoodsPicDao goodsPicDao;

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private RegionDao regionDao;

    @Autowired
    private MediaResService mediaResService;

    @Autowired
    private BonusTypeDao bonusTypeDao;

    @Autowired
    private UserBonusDao userBonusDao;

    @Autowired
    private UsersDao usersDao;

    @Autowired
    private DeliveryOrderDao deliveryOrderDao;

    @Autowired
    private DeliveryGoodsDao deliveryGoodsDao;

    @Override
    public HibernateDao<OrderInfo, Integer> getEntityDao() {
        return orderInfoDao;
    }

    /**
     *
     * @param bonusIds
     * @return
     *          key:sellerId value:优惠信息
     */
    private Map<Integer, BonusItemVO> getBonus(List<Integer> bonusIds) throws ApplicationException {
        if (bonusIds == null || bonusIds.isEmpty()) {
            return null;
        }

        // TODO check一个店铺最多一张优惠卷
        Map<Integer, BonusItemVO> ret = null;

        for (Integer bonusId : bonusIds) {
            UserBonus ub = this.userBonusDao.get(bonusId);
            if (ub != null) {
                if (ret == null) {
                    ret = new HashMap<Integer, BonusItemVO>();
                }

                BonusItemVO item = new BonusItemVO();
                item.setBonusId(ub.getBonusId());
                item.setUserId(ub.getUserId());
                item.setTypeId(ub.getTypeId());
                item.setAddTime(ub.getAddTime());

                item.setUsedTime(ub.getUsedTime());
                item.setOrderId(ub.getOrderId());

                BonusType bt = this.bonusTypeDao.get(ub.getTypeId());
                if (bt != null) {
                    item.setTypeName(bt.getTypeName());
                    item.setTypeMoney(bt.getTypeMoney());
                    item.setSendStartDate(bt.getSendStartDate());
                    item.setSendEndDate(bt.getSendEndDate());

                    // 校验是否能使用
                    item.setUseStartDate(bt.getUseStartDate());
                    item.setUseEndDate(bt.getUseEndDate());
                    item.setSellerId(bt.getSellerId());
                    item.setMinGoodsAmount(bt.getMinGoodsAmount());

                    Seller s = this.sellerDao.get(bt.getSellerId());
                    item.setSellerName(s.getName());
                }

                if (ret.containsKey(item.getSellerId())) {
                    throw new ApplicationException(1020, "一个店铺只能使用一张优惠卷");
                }
                // 要保证一个店铺只能使用一张
                ret.put(item.getSellerId(), item);
            }
        }
        return ret;
    }

    /**
     * 校验生成订单的规则是否成立
     * @param ogvs
     * @throws ApplicationException
     */
    private void checkOrders(List<OrderGoodsVO> ogvs, Map<Integer, BonusItemVO> bonuses) throws ApplicationException {
        for (OrderGoodsVO ogv : ogvs) {
            if (ogv.getAmout() == null) {
                throw new ApplicationException(9999, "订单金额计算有误!");
            }
            if (ogv.getGoodsitems() == null || ogv.getGoodsitems().isEmpty()) {
                throw new ApplicationException(9999, "无产品信息!");
            }
            for (GoodsInfoVO gi : ogv.getGoodsitems()) {
                Goods g = this.goodsDao.get(gi.getGoodsId());
                if (g.getInventory() == null || g.getInventory().intValue() <= 0) {
                    throw new ApplicationException(1020, g.getGoodsName() + "已无库存量，请更换产品后再订购!");
                }
            }
            // 取得店铺的信息
            Seller s = sellerDao.find(ogv.getSellerId());
            // 店铺名称
            String sellerName = s.getName();
            boolean isOpen = (s.getIsopen() == null) ? false : s.getIsopen();
            if (!isOpen) {
                throw new ApplicationException(1010, sellerName + "已经关店了,请您在店家开店时订购!");
            }

            if (StringUtils.isBlank(s.getDeliveryStart()) || StringUtils.isBlank(s.getDeliveryEnd())) {
                // 配送开始时间和结束时间,任意一个值为null,忽略配送时间
            } else {
                // 当天日期
                String curDay = DateUtils.getDate();
                Date curTime = DateUtils.getSysTimestamp();
                // 获得当天的配送时间
                Date deliveryStart = DateUtils.parseDate(curDay + " " + s.getDeliveryStart());
                Date deliveryEnd = DateUtils.parseDate(curDay + " " + s.getDeliveryEnd());

                if (curTime.getTime() >= deliveryStart.getTime() && curTime.getTime() <= deliveryEnd.getTime()) {
                    // 符合配送时间
                } else {
                    throw new ApplicationException(1010, "目前不在商家" + sellerName + "的配送时间(" + s.getDeliveryStart() + "~" + s.getDeliveryEnd() +")内,请选择其他店铺的商品订购!");
                }
            }

            if (s.getMinChange() == null || s.getMinChange() == 0.0) {
                // 无最低消费要求
            } else {
                // 最低消费
                if (ogv.getAmout() < s.getMinChange()) {
                    throw new ApplicationException(1010, "您的消费小于商家" + sellerName + "的最低消费(" + s.getMinChange() + "),请重新选择商品订购!");
                }
            }

            // 以下是校验使用的优惠卷
            if (bonuses == null || bonuses.isEmpty()) {
                // 未使用优惠卷
                continue;
            }
            if (!bonuses.containsKey(s.getSellerId())) {
                // 未使用优惠卷(此商家)
                continue;
            }

            BonusItemVO bonuse = bonuses.get(s.getSellerId());
            if (bonuse.getUsedTime() != null) {
                throw new ApplicationException(1020, bonuse.getBonusId() + "优惠卷已被使用,请您确认!");
            }
            if (bonuse.getMinGoodsAmount() == null || bonuse.getMinGoodsAmount() == 0.0) {
                // 优惠卷中没有指定金额,所以是直接减免优惠卷
            } else {
                if (ogv.getAmout() < bonuse.getMinGoodsAmount()) {
                    throw new ApplicationException(1020, "优惠卷使用条件未此优惠卷满足最小金额(" + bonuse.getMinGoodsAmount() + ")的要求,不能使用!");
                }
            }
        }
    }

    @Transactional(readOnly = false)
    public List<Integer> add(AddOrderVO vo) throws ApplicationException {
        List<OrderItem> items = vo.getItems();
        List<Integer> ret = new ArrayList<Integer>();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return ret;
        }

        List<Integer> bonusIds = vo.getBonusIds();
        Map<Integer, BonusItemVO> bonuses = getBonus(bonusIds);

        // 生成订单时，要校验每个商品的库存是否充实
        List<OrderGoodsVO> ogvs = analysisOrderItem(vo);
        this.checkOrders(ogvs, bonuses);
        for (OrderGoodsVO ogv : ogvs) {
            OrderInfo oi = new OrderInfo();
            // 计算订单费用时使用
            Seller s = sellerDao.find(ogv.getSellerId());

            // 生成订单号
            // oi.setOrderSn("00000000000000000");
            oi.setOrderSn(sequenceDao.getSequence());
            oi.setUserId(ent.getUserId());

            // 订单状态
            oi.setOrderStatus((short) 0);
            // 商品配送情况
            oi.setShippingStatus((short) 0);
            // 支付状态
            oi.setPayStatus((short) 0);
            // 退货状态
            oi.setReturnedStatus((short) 0);

            oi.setConsignee("");
            oi.setProvince(0);
            oi.setCity(0);
            oi.setDistrict(0);
            oi.setSex((short) 0);
            oi.setAddress("");
            oi.setZipcode("");
            oi.setTel("");
            oi.setMobile("");
            oi.setEmail("");
            oi.setBestTime("");

            // 订单描述 先不实现
            oi.setPostscript("");
            // 配送费
            // 商家商品配送费
            oi.setShippingFee(s.getShippingFee());

            CalculateVO retvo = calculateOrder(ogv, s, ent.getUserId(), bonuses);
            // 商品总金额
            oi.setGoodsAmount(retvo.getGoodsAmount());
            // 应付款 (实付金额，去掉折扣等)
            oi.setOrderAmount(retvo.getAccount());

            oi.setSellerId(s.getSellerId());
            oi.setFirtDiscountFee(retvo.getFirtDiscountFee());
            oi.setFmDiscountFee(retvo.getFmDiscountFee());
            oi.setShippingDiscountFee(retvo.getShippingDiscountFee());
            oi.setHolidayDiscountFee(retvo.getHolidayDiscountFee());

            Timestamp t = new Timestamp(System.currentTimeMillis());
            // 默认订单确认和支付的时间与创建时间一致
            oi.setAddTime(t);
            oi.setConfirmTime(t);
            oi.setPayTime(t);
            oi.setShippingTime(t);
            oi.setPayNote("");

            oi.setBonusId(retvo.getBonusId());
            oi.setBonus(retvo.getBonus());
            // 保存订单表
            orderInfoDao.save(oi);

            // 保存订单商家表
            OrderSeller os = new OrderSeller();
            os.setOrderId(oi.getOrderId());
            os.setSellerId(ogv.getSellerId());
            // 店铺当时优惠信息
            os.setIsFirst(s.getIsFirst());
            os.setFirstAmount(s.getFirstAmount());
            os.setIsFullMinus(s.getIsFullMinus());
            os.setFullAmount(s.getFullAmount());
            os.setMinusAmount(s.getMinusAmount());
            os.setIsShippingFree(s.getIsShippingFree());
            os.setShippingFee(s.getShippingFee());
            os.setIsHoliday(s.getIsHoliday());
            os.setDiscount(s.getDiscount());
            orderSellerDao.save(os);

            short sortorder = 1;
            // 循环分组中的商品
            for (GoodsInfoVO o : ogv.getGoodsitems()) {
                OrderGoods og = new OrderGoods();
                og.setOrderId(oi.getOrderId());
                og.setGoodsId(o.getGoodsId());
                og.setGoodsName(o.getGoodsName());
                og.setGoodsSn(o.getGoodsSn());
                og.setGoodsNumber(o.getGoodsNumber());
                og.setGoodsPrice(o.getGoodsPrice());
                og.setGoodsAttr("");
                og.setSortOrder(sortorder);
                og.setMeasureUnit(o.getMeasureUnit());

                Goods g = goodsDao.get(o.getGoodsId());
                if (StringUtils.isNotBlank(g.getSpeNote())) {
                    og.setSpeNote(g.getSpeNote());
                } else {
                    og.setSpeNote("");
                }
                sortorder++;
                // 保存订单商品表
                orderGoodsDao.save(og);
            }

            // 更新优惠卷
            if (retvo.getBonusId() != null && retvo.getBonusId().intValue() > 0) {
                UserBonus ub = userBonusDao.get(retvo.getBonusId());
                if (ub != null) {
                    ub.setOrderId(oi.getOrderId());
                    ub.setUsedTime(DateUtils.getSysTimestamp());
                    this.userBonusDao.save(ub);
                }
            }
            // 将生成的订单主键返回
            ret.add(oi.getOrderId());
        }

        return ret;
    }

    @Transactional(readOnly = false)
    public void submit(SubmitOrderVO vo) {
        List<Integer> ret = new ArrayList<Integer>();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return;
        }
        if (vo.getOrderIds() == null || vo.getOrderIds().isEmpty()) {
            return;
        }

        // 取得订单号
        List<OrderInfo> ois = orderInfoDao.find(Restrictions.in("orderId", vo.getOrderIds()), Restrictions.eq("userId", ent.getUserId()));
        for (OrderInfo oi : ois) {
            /// 校验是不是本人的订单
            if (oi == null) {
                return;
            }

            // 订单状态 1: 客户提交订单
            oi.setOrderStatus((short) 1);
            oi.setConsignee(vo.getConsignee());
            oi.setProvince(vo.getProvince());
            oi.setCity(vo.getCity());
            oi.setDistrict(vo.getDistrict());
            oi.setSex(vo.getSex());
            oi.setAddress(vo.getAddress());
            oi.setZipcode("");
            oi.setTel("");
            oi.setMobile(vo.getMobile());
            oi.setEmail("");
            oi.setBestTime("");
            oi.setPayNote(vo.getPayNote());
            this.orderInfoDao.save(oi);

//            // TODO 推送消息到商家,推送已放到支付完成中
//            Seller s = this.sellerDao.get(oi.getSellerId());
//            Users ub = this.usersDao.get(s.getUserId());
//            if (StringUtils.isNotBlank(ub.getSRegistrationId())) {
//                String msg = oi.getOrderId()+","+oi.getOrderSn();
//                logger.info("msg=" + msg);
//                MessageUtils.sendmsg2bus(msg, ub.getSRegistrationId());
//            }
        }
    }

    /**
     * 对每个商家进行计算
     * @param ogv
     * @param s
     * @param userId
     * @return
     */
    private CalculateVO calculateOrder(OrderGoodsVO ogv, Seller s, Integer userId, Map<Integer, BonusItemVO> bonuses) {
        CalculateVO vo = new CalculateVO();
        double account = 0.0;
        double goodsAmount = 0.0;

        // 循环分组中的商品
        for (GoodsInfoVO o : ogv.getGoodsitems()) {
            int goodsNumber = 0;
            if (o.getGoodsNumber() != null) {
                goodsNumber = o.getGoodsNumber();
            }
            double goodsPrice = 0.0;
            if (o.getGoodsPrice() != null) {
                goodsPrice = o.getGoodsPrice();
            }
            account += goodsNumber * goodsPrice;
            goodsAmount += goodsNumber * goodsPrice;
        }
        vo.setGoodsAmount(goodsAmount);
        // 首减
        if (s.getIsFirst() && !isSold(s.getSellerId(), userId)) {
            // 首减
            account = account - s.getFirstAmount();
            // 首减额
            vo.setFirtDiscountFee(s.getFirstAmount());
        }
        // 满减
        if (s.getIsFullMinus()) {
            if (account >= s.getFullAmount()) {
                account = account - s.getMinusAmount();
                // 满减额
                vo.setFmDiscountFee(s.getMinusAmount());
            }
        }
        vo.setBonus(0);
        vo.setBonusId(0);
        // 使用优惠卷
        if (bonuses != null && bonuses.containsKey(s.getSellerId())) {
            BonusItemVO item = bonuses.get(s.getSellerId());
            if (item.getMinGoodsAmount().doubleValue() == 0.0) {
                account = account - item.getTypeMoney();

                vo.setBonusId(item.getBonusId());
                vo.setBonus(item.getTypeMoney());
            } else {
                if (account >= item.getMinGoodsAmount().doubleValue()) {
                    // 满多少,减多少
                    account = account - item.getTypeMoney();

                    vo.setBonusId(item.getBonusId());
                    vo.setBonus(item.getTypeMoney());
                }
            }
        }
        // 是否免运费
        if (!s.getIsShippingFree()) {
            account = account + s.getShippingFee();
        } else {
            // 免除运费
            vo.setShippingDiscountFee(s.getShippingFee());
        }

        vo.setAccount(account);
        return vo;
    }

    /**
     * 是否有过成交的订单
     * @param sellerId
     * @param userId
     * @return
     */
    private boolean isSold(Integer sellerId, Integer userId) {
        // OrderInfo oi = orderInfoDao.findUnique(Restrictions.eq("sellerId", sellerId), Restrictions.eq("userId", userId), Restrictions.eq("orderStatus", (short)1));
        // 只判断数据，只有存在就不能首减！！！
        List<OrderInfo> ois = orderInfoDao.find(Restrictions.eq("sellerId", sellerId), Restrictions.eq("userId", userId));
        if (ois != null && !ois.isEmpty()) {
            return true;
        }
        return false; //""
    }

    /**
     * 分析传入的订单信息，得到商品归属信息，归并
     * @param vo
     */
    private List<OrderGoodsVO> analysisOrderItem(AddOrderVO vo) {
        List<OrderItem> items = vo.getItems();

        Map<Integer, List<OrderItem>> map = new HashMap<Integer, List<OrderItem>>();
        // 合并
        for (OrderItem item : items) {
            if (map.containsKey(item.getSellerId())) {
                List<OrderItem> ois = (List<OrderItem>) map.get(item.getSellerId());
                ois.add(item);
            } else {
                List<OrderItem> ois = new ArrayList<OrderItem>();
                ois.add(item);
                map.put(item.getSellerId(), ois);
            }
        }

        // 计算和整理
        Set<Integer> keys = map.keySet();
        List<OrderGoodsVO> rets = new ArrayList<OrderGoodsVO>();
        for (Integer key : keys) {
            OrderGoodsVO og = new OrderGoodsVO();
            og.setSellerId(key);

            // 本商店货物总金额
            double amount = 0.0;
            // 取出分组的资源
            List<OrderItem> ois  = (List<OrderItem>) map.get(key);
            List<GoodsInfoVO> gil= new ArrayList<GoodsInfoVO>();
            for (OrderItem item : ois) {
                GoodsInfoVO gio = new GoodsInfoVO();

                gio.setGoodsId(item.getGoodsId());
                Goods g = this.goodsDao.get(item.getGoodsId());
                gio.setGoodsNumber(item.getGoodsNumber());
                gio.setGoodsPrice(item.getGoodsPrice());

                gio.setGoodsSn(g.getGoodsSn());
                gio.setGoodsName(g.getGoodsName());
                gio.setMeasureUnit(g.getMeasureUnit());
                // gio.setGoodsName(item.getGoodsName());
                // gio.setGoodsSn(item.getGoodsSn());
                // gio.setMeasureUnit(item.getMeasureUnit());
                amount += item.getGoodsPrice() * item.getGoodsNumber();
                gil.add(gio);
            }
            og.setGoodsitems(gil);
            // 先做最简单运算, 计算订单金额
            og.setAmout(amount);
            rets.add(og);
        }

        return rets;
    }

    /**
     * 商家查询自己某一订单
     * @param vo
     * @return
     */
    public List<OrderVO> detailsbybus(DetailOrderVO vo) {
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return null;
        }

        // 一用户,一个店铺
        List<Seller> ses = this.sellerDao.find(Restrictions.eq("userId", ent.getUserId()));
        if (ses == null || ses.isEmpty()) {
            return null;
        }
        Seller s = ses.get(0);
        List<OrderVO> ret = new ArrayList<OrderVO>();
        List<OrderInfo> ois = orderInfoDao.find(Restrictions.in("orderId", vo.getOrderIds()),
                Restrictions.eq("sellerId", s.getSellerId()));

        return getOrderInfos(ois);
    }

    /**
     * 查询自己某些订单
     * @param vo
     * @return
     */
    public List<OrderVO> details(DetailOrderVO vo) {
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return null;
        }

        List<OrderInfo> ois = orderInfoDao.find(Restrictions.in("orderId", vo.getOrderIds()),
                Restrictions.eq("userId", ent.getUserId()));

        return getOrderInfos(ois);
    }

    /**
     * 提取订单信息
     * @param ois
     * @return
     */
    private List<OrderVO> getOrderInfos(List<OrderInfo> ois) {
        List<OrderVO> ret = new ArrayList<OrderVO>();
        for (OrderInfo oi : ois) {
            // 表结构中是 1对多的关系，但这里使用了1对1 的关系，orderinfo : orderseller 一个订单对应一个商家
            OrderSeller os = orderSellerDao.findUnique(Restrictions.eq("orderId", oi.getOrderId()));
            Seller s = sellerDao.find(os.getSellerId());

            OrderVO orderVO = new OrderVO();
            orderVO.setSellerId(os.getSellerId());
            // 商家名称
            orderVO.setSellerName(s.getName());
            orderVO.setIsFirst(os.getIsFirst());
            orderVO.setFirstAmount(os.getFirstAmount());
            orderVO.setIsFullMinus(os.getIsFullMinus());
            orderVO.setFullAmount(os.getFullAmount());
            orderVO.setMinusAmount(os.getMinusAmount());
            orderVO.setIsShippingFree(os.getIsShippingFree());
            orderVO.setShippingFee(os.getShippingFee());

            orderVO.setOrderId(oi.getOrderId());
            orderVO.setOrderSn(oi.getOrderSn());
            orderVO.setOrderStatus(oi.getOrderStatus());
            orderVO.setShippingStatus(oi.getShippingStatus());
            orderVO.setPayStatus(oi.getPayStatus());
            // 收件人
            orderVO.setConsignee(oi.getConsignee());
            orderVO.setSex(oi.getSex());
            orderVO.setProvince(oi.getProvince());
            orderVO.setCity(oi.getCity());
            orderVO.setDistrict(oi.getDistrict());

            orderVO.setProvinceNm(this.getRegion(oi.getProvince()));
            orderVO.setCityNm(this.getRegion(oi.getCity()));
            orderVO.setDistrictNm(this.getRegion(oi.getDistrict()));

            orderVO.setAddress(oi.getAddress());
            orderVO.setZipcode(oi.getZipcode());

            orderVO.setMobile(oi.getMobile());
            orderVO.setBestTime(oi.getBestTime());
            orderVO.setGoodsAmount(oi.getGoodsAmount());
            orderVO.setOrderAmount(oi.getOrderAmount());

            Timestamp addTime = oi.getAddTime();
            orderVO.setAddTime(DateUtils.dateFormat(addTime));

            if (addTime.equals(oi.getConfirmTime())) {
                orderVO.setConfirmTime("");
            } else {
                orderVO.setConfirmTime(DateUtils.dateFormat(oi.getConfirmTime()));
            }

            if (addTime.equals(oi.getPayTime())) {
                orderVO.setPayTime("");
            } else {
                orderVO.setPayTime(DateUtils.dateFormat(oi.getPayTime()));
            }

            if (addTime.equals(oi.getShippingTime())) {
                orderVO.setShippingTime("");
            } else {
                orderVO.setShippingTime(DateUtils.dateFormat(oi.getShippingTime()));
            }
            orderVO.setPayNote(oi.getPayNote());
//            orderVO.setFirtDiscountFee(oi.getFirtDiscountFee());
//            orderVO.setFmDiscountFee(oi.getFmDiscountFee());
//            orderVO.setShippingDiscountFee(oi.getShippingDiscountFee());

            if (oi.getFirtDiscountFee() == null || oi.getFirtDiscountFee() == 0.0) {
                orderVO.setIsFirtDiscountFee(false);
            } else {
                orderVO.setIsFirtDiscountFee(true);
            }
            orderVO.setFirtDiscountFee(oi.getFirtDiscountFee());

            if (oi.getFmDiscountFee() == null || oi.getFmDiscountFee() == 0.0) {
                orderVO.setIsFmDiscountFee(false);
            } else {
                orderVO.setIsFmDiscountFee(true);
            }
            orderVO.setFmDiscountFee(oi.getFmDiscountFee());

            if (oi.getShippingDiscountFee() == null || oi.getShippingDiscountFee() == 0.0) {
                orderVO.setIsShippingDiscountFee(false);
            } else {
                orderVO.setIsShippingDiscountFee(true);
            }
            orderVO.setShippingDiscountFee(oi.getShippingDiscountFee());

            PropertiesLoader loader = new PropertiesLoader("env.properties");
            int speFlag = loader.getInteger("SPE_GT_ID", 0);
            if (s.getGtId().shortValue() == (short) speFlag) {
                orderVO.setSpe("1");
                // 特产商品 设置运单信息
                orderVO.setDeliveryitems(getDeliveryInfo(oi.getOrderId()));
            } else {
                orderVO.setSpe("0");
            }

            // -----优惠卷信息 ---
            if (oi.getBonusId() == null || oi.getBonusId().intValue() == 0) {
                orderVO.setBonusId(0);
                orderVO.setBonus(0.0);
            } else {
                orderVO.setBonusId(oi.getBonusId());
                orderVO.setBonus(oi.getBonus());

                UserBonus ub = this.userBonusDao.get(oi.getBonusId());
                if (ub != null) {
                    BonusType bt = this.bonusTypeDao.get(ub.getTypeId());
                    orderVO.setTypeId(ub.getTypeId());
                    orderVO.setTypeName(bt.getTypeName());
                    orderVO.setTypeMoney(bt.getTypeMoney());
                    orderVO.setMinGoodsAmount(bt.getMinGoodsAmount());
                    orderVO.setUsedTime(ub.getUsedTime());
                }
            }
            // --------------------
            // 订单商品明细
            List<OrderGoods> ogs = orderGoodsDao.findbyorder("sortOrder", true, Restrictions.eq("orderId", oi.getOrderId()));
            List<OrderItemVO> items = null;
            for (OrderGoods og : ogs) {
                if (items == null)
                    items = new ArrayList<OrderItemVO>();

                OrderItemVO oivo = new OrderItemVO();
                // oivo.setSellerId();
                oivo.setRecId(og.getRecId());
                oivo.setGoodsId(og.getGoodsId());
                oivo.setGoodsSn(og.getGoodsSn());
                oivo.setGoodsName(og.getGoodsName());
                oivo.setGoodsPrice(og.getGoodsPrice());
                oivo.setGoodsNumber(og.getGoodsNumber());
                oivo.setMeasureUnit(og.getMeasureUnit());
                if (og.getCommentId() == null || og.getCommentId().intValue() == 0) {
                    oivo.setIsComment(false);
                    oivo.setCommentId(0);
                } else {
                    oivo.setIsComment(true);
                    oivo.setCommentId(og.getCommentId());
                }
                // 带排序的查询
                List<GoodsPic> gps = goodsPicDao.findbyorder("sortOrder", true, Restrictions.eq("goodsId", og.getGoodsId()),
                        Restrictions.eq("isDelete", false));

                String pics = "";
                boolean isFirst = false;
                for (GoodsPic gp : gps) {
                    // MediaRes mr = mediaResDao.find(gp.getMediaId());
                    if (!isFirst) {
                        // pics += gp.getMediaId() + "." + FileNameUtils.getExtName(mr.getFileName());
                        pics += mediaResService.getResUrl(gp.getMediaId());
                        isFirst = true;
                    } else {
                        pics += "," + mediaResService.getResUrl(gp.getMediaId());
                    }
                }
                oivo.setPics(pics);
                items.add(oivo);
            }
            orderVO.setItems(items);
            // return orderVO;
            ret.add(orderVO);
        }

        return ret;
    }

    private String getRegion(Integer id) {
        Region r = this.regionDao.get(id);
        if (r == null) {
            return id.toString();
        }
        return r.getName();
    }

    /**
     * 客户自己的查询
     * @param vo
     * @return
     */
    public QueryOrderInfoRetVO querybyself(QueryOrderVO vo) {
        QueryOrderInfoRetVO o = new QueryOrderInfoRetVO();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return o;
        }

        List<OrderVO> orders = new ArrayList<OrderVO>();
        List<OrderInfo> ois = null;

        //  客户端 订单状态，1:已完成 2:待收货 3:退款中
        // 订单状态 0预定单,1提交定单,2商家确认,3已取消,4无效,5退货
        if ("1".equals(vo.getStatus())) {
            // 订单状态 为 1确认 商品配送情况 2已收货
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("userId", ent.getUserId()),
                    Restrictions.eq("orderStatus", (short) 2), Restrictions.eq("shippingStatus", (short) 2),
                    Restrictions.eq("payStatus", (short) 1));
        } else if ("2".equals(vo.getStatus())) {
            // 订单状态 为 0未确认
            // 订单状态 为 1确认 商品配送情况 0未发货
            // 订单状态 为 1确认 商品配送情况 1已发货,
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("userId", ent.getUserId()),
                    // Restrictions.or(Restrictions.eq("orderStatus", (short) 0), Restrictions.eq("orderStatus", (short) 1),
                    Restrictions.or(Restrictions.and(Restrictions.eq("orderStatus", (short) 1), Restrictions.eq("payStatus", (short) 1)),
                            Restrictions.and(Restrictions.eq("orderStatus", (short) 2), Restrictions.eq("shippingStatus", (short) 0), Restrictions.eq("payStatus", (short) 1)),
                            Restrictions.and(Restrictions.eq("orderStatus", (short) 2), Restrictions.eq("shippingStatus", (short) 1), Restrictions.eq("payStatus", (short) 1))));
        } else if ("3".equals(vo.getStatus())) {
            // 退款
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("userId", ent.getUserId()),
                    Restrictions.eq("orderStatus", (short) 5));
        }
        for (OrderInfo oi : ois) {
logger.info("in querybyself for oi:ois");
            // 表结构中是 1对多的关系，但这里使用了1对1 的关系，orderinfo : orderseller 一个订单对应一个商家
            OrderSeller os = orderSellerDao.findUnique(Restrictions.eq("orderId", oi.getOrderId()));
            Seller s = sellerDao.find(os.getSellerId());

            OrderVO orderVO = new OrderVO();
            orderVO.setSellerId(os.getSellerId());
            // 商家名称
            orderVO.setSellerName(s.getName());
            orderVO.setIsFirst(os.getIsFirst());
            orderVO.setFirstAmount(os.getFirstAmount());
            orderVO.setIsFullMinus(os.getIsFullMinus());
            orderVO.setFullAmount(os.getFullAmount());
            orderVO.setMinusAmount(os.getMinusAmount());
            orderVO.setIsShippingFree(os.getIsShippingFree());
            orderVO.setShippingFee(os.getShippingFee());

            orderVO.setOrderId(oi.getOrderId());
            orderVO.setOrderSn(oi.getOrderSn());
            orderVO.setOrderStatus(oi.getOrderStatus());
            orderVO.setShippingStatus(oi.getShippingStatus());
            orderVO.setPayStatus(oi.getPayStatus());
            // 收件人
            orderVO.setConsignee(oi.getConsignee());
            orderVO.setSex(oi.getSex());
            orderVO.setProvince(oi.getProvince());
            orderVO.setCity(oi.getCity());
            orderVO.setDistrict(oi.getDistrict());

            orderVO.setProvinceNm(this.getRegion(oi.getProvince()));
            orderVO.setCityNm(this.getRegion(oi.getCity()));
            orderVO.setDistrictNm(this.getRegion(oi.getDistrict()));

            orderVO.setAddress(oi.getAddress());
            orderVO.setZipcode(oi.getZipcode());

            orderVO.setMobile(oi.getMobile());
            orderVO.setBestTime(oi.getBestTime());
            orderVO.setGoodsAmount(oi.getGoodsAmount());
            orderVO.setOrderAmount(oi.getOrderAmount());

            Timestamp addTime = oi.getAddTime();
            orderVO.setAddTime(DateUtils.dateFormat(addTime));

            if (addTime.equals(oi.getConfirmTime())) {
                orderVO.setConfirmTime("");
            } else {
                orderVO.setConfirmTime(DateUtils.dateFormat(oi.getConfirmTime()));
            }

            if (addTime.equals(oi.getPayTime())) {
                orderVO.setPayTime("");
            } else {
                orderVO.setPayTime(DateUtils.dateFormat(oi.getPayTime()));
            }

            if (addTime.equals(oi.getShippingTime())) {
                orderVO.setShippingTime("");
            } else {
                orderVO.setShippingTime(DateUtils.dateFormat(oi.getShippingTime()));
            }
            orderVO.setPayNote(oi.getPayNote());

            if (oi.getFirtDiscountFee() == null || oi.getFirtDiscountFee() == 0.0) {
                orderVO.setIsFirtDiscountFee(false);
            } else {
                orderVO.setIsFirtDiscountFee(true);
            }
            orderVO.setFirtDiscountFee(oi.getFirtDiscountFee());

            if (oi.getFmDiscountFee() == null || oi.getFmDiscountFee() == 0.0) {
                orderVO.setIsFmDiscountFee(false);
            } else {
                orderVO.setIsFmDiscountFee(true);
            }
            orderVO.setFmDiscountFee(oi.getFmDiscountFee());

            if (oi.getShippingDiscountFee() == null || oi.getShippingDiscountFee() == 0.0) {
                orderVO.setIsShippingDiscountFee(false);
            } else {
                orderVO.setIsShippingDiscountFee(true);
            }
            orderVO.setShippingDiscountFee(oi.getShippingDiscountFee());


            PropertiesLoader loader = new PropertiesLoader("env.properties");
            int speFlag = loader.getInteger("SPE_GT_ID", 0);
            if (s.getGtId().shortValue() == (short) speFlag) {
                orderVO.setSpe("1");
                // 特产商品 设置运单信息
                orderVO.setDeliveryitems(getDeliveryInfo(oi.getOrderId()));
            } else {
                orderVO.setSpe("0");
            }
            // -----优惠卷信息 ---
            if (oi.getBonusId() == null || oi.getBonusId().intValue() == 0) {
                orderVO.setBonusId(0);
                orderVO.setBonus(0.0);
            } else {
                orderVO.setBonusId(oi.getBonusId());
                orderVO.setBonus(oi.getBonus());

                UserBonus ub = this.userBonusDao.get(oi.getBonusId());
                if (ub != null) {
                    BonusType bt = this.bonusTypeDao.get(ub.getTypeId());
                    orderVO.setTypeId(ub.getTypeId());
                    orderVO.setTypeName(bt.getTypeName());
                    orderVO.setTypeMoney(bt.getTypeMoney());
                    orderVO.setMinGoodsAmount(bt.getMinGoodsAmount());
                    orderVO.setUsedTime(ub.getUsedTime());
                }
            }
            // --------------------
            // 订单商品明细
            List<OrderGoods> ogs = orderGoodsDao.findbyorder("sortOrder", true, Restrictions.eq("orderId", oi.getOrderId()));
            List<OrderItemVO> items = null;
            for (OrderGoods og : ogs) {
                if (items == null)
                    items = new ArrayList<OrderItemVO>();

                OrderItemVO oivo = new OrderItemVO();
                // oivo.setSellerId();
                oivo.setRecId(og.getRecId());
                oivo.setGoodsId(og.getGoodsId());
                oivo.setGoodsSn(og.getGoodsSn());
                oivo.setGoodsName(og.getGoodsName());
                oivo.setGoodsPrice(og.getGoodsPrice());
                oivo.setGoodsNumber(og.getGoodsNumber());
                oivo.setMeasureUnit(og.getMeasureUnit());
                if (og.getCommentId() == null || og.getCommentId().intValue() == 0) {
                    oivo.setIsComment(false);
                    oivo.setCommentId(0);
                } else {
                    oivo.setIsComment(true);
                    oivo.setCommentId(og.getCommentId());
                }
                // 带排序的查询
                List<GoodsPic> gps = goodsPicDao.findbyorder("sortOrder", true, Restrictions.eq("goodsId", og.getGoodsId()),
                        Restrictions.eq("isDelete", false));

                String pics = "";
                boolean isFirst = false;
                for (GoodsPic gp : gps) {
                    // MediaRes mr = mediaResDao.find(gp.getMediaId());
                    if (!isFirst) {
                        // pics += gp.getMediaId() + "." + FileNameUtils.getExtName(mr.getFileName());
                        pics += mediaResService.getResUrl(gp.getMediaId());
                        isFirst = true;
                    } else {
                        pics += "," + mediaResService.getResUrl(gp.getMediaId());
                    }
                }
                oivo.setPics(pics);
                items.add(oivo);
            }
            orderVO.setItems(items);

            orders.add(orderVO);
        }

        o.setOrders(orders);
        return o;
    }

    private List<DeliveryVO> getDeliveryInfo(Integer orderId) {
        List<DeliveryVO> ret = new ArrayList<DeliveryVO>();
        List<DeliveryOrder> dors = deliveryOrderDao.find(Restrictions.eq("orderId", orderId));
        for (DeliveryOrder dor : dors) {
            DeliveryVO item = new DeliveryVO();
            item.setDeliveryId(dor.getDeliveryId());
            item.setDeliverySn(dor.getDeliverySn());
            item.setExpressName(dor.getExpressName());
            item.setOrderId(dor.getOrderId());
            item.setAddTime(dor.getAddTime());
            item.setStatus(dor.getStatus());

            List<DeliveryGoods> dgs = deliveryGoodsDao.find(Restrictions.eq("deliveryId", dor.getDeliveryId()));
            for (DeliveryGoods dg : dgs) {
                if (item.getDeliveryGoodses() == null) {
                    item.setDeliveryGoodses(new ArrayList<DeliveryGoodsVO>());
                }
                DeliveryGoodsVO deliveryGoodsVO = new DeliveryGoodsVO();
                deliveryGoodsVO.setGoodsId(dg.getGoodsId());
                deliveryGoodsVO.setGoodsName(dg.getGoodsName());
                deliveryGoodsVO.setGoodsSn(dg.getGoodsSn());
                deliveryGoodsVO.setGoodsNumber(dg.getGoodsNumber());
                deliveryGoodsVO.setGoodsPrice(dg.getGoodsPrice());
                deliveryGoodsVO.setMeasureUnit(dg.getMeasureUnit());
                item.getDeliveryGoodses().add(deliveryGoodsVO);
            }

            ret.add(item);
        }
        return ret;
    }

    @Transactional(readOnly = false)
    public ResultObj receivingConfirmationBySelf(ReceivingOrderVO vo) {
        ResultObj o = new ResultObj();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            o.setErrcode(9999);
            return o;
        }

        // 校验是本人的订单
        OrderInfo oi = this.orderInfoDao.findUnique(Restrictions.eq("userId", ent.getUserId()),
                Restrictions.eq("orderId", vo.getOrderId()));
        if (oi == null) {
            o.setErrcode(3333);
            o.setErrmsg("无此订单");
            return o;
        }

        if (oi.getOrderStatus().shortValue() != 2) {
            o.setErrcode(1111);
            o.setErrmsg("商家还未确认发货,请等待!");
            return o;
        }
        // 已收货
        oi.setShippingStatus((short) 2);
        oi.setReceivingTime(DateUtils.getSysTimestamp());
        this.orderInfoDao.save(oi);

        o.setErrcode(0);
        o.setErrmsg("客户成功确认收货");
        return o;
    }

    @Transactional(readOnly = false)
    public ResultObj receivingConfirmationSpeBySelf(ReceivingOrderSpeVO vo) {
        ResultObj o = new ResultObj();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            o.setErrcode(9999);
            return o;
        }

        // 校验是本人的订单
        OrderInfo oi = this.orderInfoDao.findUnique(Restrictions.eq("userId", ent.getUserId()),
                Restrictions.eq("orderId", vo.getOrderId()));
        if (oi == null) {
            o.setErrcode(3333);
            o.setErrmsg("无此订单");
            return o;
        }

//        // 已收货
//        oi.setShippingStatus((short) 2);
//        oi.setReceivingTime(DateUtils.getSysTimestamp());
//        this.orderInfoDao.save(oi);
        DeliveryOrder dor = deliveryOrderDao.findUnique(Restrictions.eq("orderId", vo.getOrderId()), Restrictions.eq("deliveryId", vo.getDeliveryId()));
        if (dor == null) {
            o.setErrcode(3333);
            o.setErrmsg("无此运单");
            return o;
        }

        dor.setStatus((short)2);
        this.deliveryOrderDao.save(dor);
        /// ==== 运单与订单商品相对应
        List<OrderGoods> ogs = this.orderGoodsDao.find(Restrictions.eq("orderId", vo.getOrderId()));

        List<DeliveryOrder> dors = this.deliveryOrderDao.find(Restrictions.eq("orderId", vo.getOrderId()), Restrictions.eq("status", (short) 2));
        List<Integer> dorids = new ArrayList<Integer>();
        for (DeliveryOrder d : dors) {
            dorids.add(d.getDeliveryId());
        }
        List<DeliveryGoods> dgs = this.deliveryGoodsDao.find(Restrictions.in("deliveryId", dorids));
        boolean isEq = true;
        if (ogs == null || ogs.isEmpty() || dgs == null || dgs.isEmpty()) {
            // nothing
            isEq = false;
        } else if (dgs.size() < ogs.size()) {
            // nothing
            isEq = false;
        } else {
            Map<Integer, Integer> map = new HashMap<Integer, Integer>();
            for (DeliveryGoods dg : dgs) {
                if (map.containsKey(dg.getGoodsId())) {
                    Integer count = (Integer) map.get(dg.getGoodsId());
                    count += dg.getGoodsNumber();
                    map.put(dg.getGoodsId(), count);
                } else {
                    map.put(dg.getGoodsId(), dg.getGoodsNumber().intValue());
                }
            }
            for (OrderGoods og : ogs) {
                if (!map.containsKey(og.getGoodsId())) {
                    isEq = false;
                    break;
                }
                Integer count = map.get(og.getGoodsId());
                if (count.intValue() != og.getGoodsNumber().intValue()) {
                    isEq = false;
                    break;
                }
            }
        }

        if (isEq) {
            // 已收货
            oi.setOrderStatus((short) 2);
            oi.setReceivingTime(DateUtils.getSysTimestamp());
            this.orderInfoDao.save(oi);
        }
        /// ==== 都确认完成才算整个订单完成确认

        o.setErrcode(0);
        o.setErrmsg("客户成功确认收货");
        return o;
    }

    /**
     * 商家查询订单
     * @param vo
     * @return
     */
    public QueryOrderInfoRetVO querybybus(QueryOrderVO vo) {
        QueryOrderInfoRetVO o = new QueryOrderInfoRetVO();
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return o;
        }
        // 一个用户有且仅有一个店铺
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            return o;
        }

        //  商家端 订单状态，1:待处理 2:已完成 3:处理中
        // 订单状态 0预定单,1提交定单,2商家确认,3已取消,4无效,5退货
        List<OrderVO> orders = new ArrayList<OrderVO>();
        List<OrderInfo> ois = null;
        if ("1".equals(vo.getStatus())) {
            // 订单状态 为 1提交定单
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("sellerId", s.getSellerId()),
                    Restrictions.eq("orderStatus", (short) 1), Restrictions.eq("payStatus", (short) 1));
        } else if ("2".equals(vo.getStatus())) {
            // 订单状态 为 2商家确认
            // 配送状态 为 2已收货
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("sellerId", s.getSellerId()),
                    Restrictions.eq("orderStatus", (short) 2), Restrictions.eq("shippingStatus", (short) 2)
                    , Restrictions.eq("payStatus", (short) 1));
        } else if ("3".equals(vo.getStatus())) {
//            // 退款
//            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("userId", ent.getUserId()),
//                    Restrictions.eq("orderStatus", (short) 5));
            // 订单状态 为 2商家确认
            // 配送状态 不为 2已收货
            ois = orderInfoDao.findbyorder("addTime", false, Restrictions.eq("sellerId", s.getSellerId()),
                    Restrictions.eq("orderStatus", (short) 2), Restrictions.ne("shippingStatus", (short) 2)
                    , Restrictions.eq("payStatus", (short) 1));
        }

        for (OrderInfo oi : ois) {

            OrderSeller os = orderSellerDao.findUnique(Restrictions.eq("orderId", oi.getOrderId()));
            OrderVO orderVO = new OrderVO();
            orderVO.setSellerId(os.getSellerId());
            // 商家名称
            orderVO.setSellerName(s.getName());
            orderVO.setIsFirst(os.getIsFirst());
            orderVO.setFirstAmount(os.getFirstAmount());
            orderVO.setIsFullMinus(os.getIsFullMinus());
            orderVO.setFullAmount(os.getFullAmount());
            orderVO.setMinusAmount(os.getMinusAmount());
            orderVO.setIsShippingFree(os.getIsShippingFree());
            orderVO.setShippingFee(os.getShippingFee());

            orderVO.setOrderId(oi.getOrderId());
            orderVO.setOrderSn(oi.getOrderSn());
            orderVO.setOrderStatus(oi.getOrderStatus());
            orderVO.setShippingStatus(oi.getShippingStatus());
            orderVO.setPayStatus(oi.getPayStatus());
            // 收件人
            orderVO.setConsignee(oi.getConsignee());
            orderVO.setSex(oi.getSex());

            orderVO.setProvince(oi.getProvince());
            orderVO.setCity(oi.getCity());
            orderVO.setDistrict(oi.getDistrict());

            orderVO.setProvinceNm(this.getRegion(oi.getProvince()));
            orderVO.setCityNm(this.getRegion(oi.getCity()));
            orderVO.setDistrictNm(this.getRegion(oi.getDistrict()));

            orderVO.setAddress(oi.getAddress());
            orderVO.setZipcode(oi.getZipcode());

            orderVO.setMobile(oi.getMobile());
            orderVO.setBestTime(oi.getBestTime());
            orderVO.setGoodsAmount(oi.getGoodsAmount());
            orderVO.setOrderAmount(oi.getOrderAmount());

            Timestamp addTime = oi.getAddTime();
            orderVO.setAddTime(DateUtils.dateFormat(addTime));

            if (addTime.equals(oi.getConfirmTime())) {
                orderVO.setConfirmTime("");
            } else {
                orderVO.setConfirmTime(DateUtils.dateFormat(oi.getConfirmTime()));
            }

            if (addTime.equals(oi.getPayTime())) {
                orderVO.setPayTime("");
            } else {
                orderVO.setPayTime(DateUtils.dateFormat(oi.getPayTime()));
            }

            if (addTime.equals(oi.getShippingTime())) {
                orderVO.setShippingTime("");
            } else {
                orderVO.setShippingTime(DateUtils.dateFormat(oi.getShippingTime()));
            }
            orderVO.setPayNote(oi.getPayNote());

            if (oi.getFirtDiscountFee() == null || oi.getFirtDiscountFee() == 0.0) {
                orderVO.setIsFirtDiscountFee(false);
            } else {
                orderVO.setIsFirtDiscountFee(true);
            }
            orderVO.setFirtDiscountFee(oi.getFirtDiscountFee());

            if (oi.getFmDiscountFee() == null || oi.getFmDiscountFee() == 0.0) {
                orderVO.setIsFmDiscountFee(false);
            } else {
                orderVO.setIsFmDiscountFee(true);
            }
            orderVO.setFmDiscountFee(oi.getFmDiscountFee());

            if (oi.getShippingDiscountFee() == null || oi.getShippingDiscountFee() == 0.0) {
                orderVO.setIsShippingDiscountFee(false);
            } else {
                orderVO.setIsShippingDiscountFee(true);
            }
            orderVO.setShippingDiscountFee(oi.getShippingDiscountFee());

            PropertiesLoader loader = new PropertiesLoader("env.properties");
            int speFlag = loader.getInteger("SPE_GT_ID", 0);
            if (s.getGtId().shortValue() == (short) speFlag) {
                orderVO.setSpe("1");
                // 特产商品 设置运单信息
                orderVO.setDeliveryitems(getDeliveryInfo(oi.getOrderId()));
            } else {
                orderVO.setSpe("0");
            }
            // -----优惠卷信息 ---
            if (oi.getBonusId() == null || oi.getBonusId().intValue() == 0) {
                orderVO.setBonusId(0);
                orderVO.setBonus(0.0);
            } else {
                orderVO.setBonusId(oi.getBonusId());
                orderVO.setBonus(oi.getBonus());

                UserBonus ub = this.userBonusDao.get(oi.getBonusId());
                if (ub != null) {
                    BonusType bt = this.bonusTypeDao.get(ub.getTypeId());
                    orderVO.setTypeId(ub.getTypeId());
                    orderVO.setTypeName(bt.getTypeName());
                    orderVO.setTypeMoney(bt.getTypeMoney());
                    orderVO.setMinGoodsAmount(bt.getMinGoodsAmount());
                    orderVO.setUsedTime(ub.getUsedTime());
                }
            }
            // --------------------

            // 订单商品明细
            List<OrderGoods> ogs = orderGoodsDao.findbyorder("sortOrder", true, Restrictions.eq("orderId", oi.getOrderId()));
            List<OrderItemVO> items = null;
            for (OrderGoods og : ogs) {
                if (items == null)
                    items = new ArrayList<OrderItemVO>();

                OrderItemVO oivo = new OrderItemVO();
                // oivo.setSellerId();
                oivo.setRecId(og.getRecId());
                oivo.setGoodsId(og.getGoodsId());
                oivo.setGoodsSn(og.getGoodsSn());
                oivo.setGoodsName(og.getGoodsName());
                oivo.setGoodsPrice(og.getGoodsPrice());
                oivo.setGoodsNumber(og.getGoodsNumber());
                oivo.setMeasureUnit(og.getMeasureUnit());
                // 评价对商家无意义
                if (og.getCommentId() == null || og.getCommentId().intValue() == 0) {
                    oivo.setIsComment(false);
                    oivo.setCommentId(0);
                } else {
                    oivo.setIsComment(true);
                    oivo.setCommentId(og.getCommentId());
                }
                // 带排序的查询
                List<GoodsPic> gps = goodsPicDao.findbyorder("sortOrder", true, Restrictions.eq("goodsId", og.getGoodsId()),
                        Restrictions.eq("isDelete", false));

                String pics = "";
                boolean isFirst = false;
                for (GoodsPic gp : gps) {
                    // MediaRes mr = mediaResDao.find(gp.getMediaId());
                    if (!isFirst) {
                        // pics += gp.getMediaId() + "." + FileNameUtils.getExtName(mr.getFileName());
                        pics += mediaResService.getResUrl(gp.getMediaId());
                        isFirst = true;
                    } else {
                        pics += "," + mediaResService.getResUrl(gp.getMediaId());
                    }
                }
                oivo.setPics(pics);
                items.add(oivo);
            }
            orderVO.setItems(items);

            orders.add(orderVO);
        }

        o.setOrders(orders);
        return o;
    }

    /**
     * 商家接单
     * @param vo
     * @return
     */
    @Transactional(readOnly = false)
    public void confirmorder(ConfirmOrderVO vo) {
        LoginSession ent = loginSessionDao.get(vo.getAccess_token());
        if (ent == null) {
            return;
        }
        // 一个用户有且仅有一个店铺
        Seller s = sellerDao.findUnique(Restrictions.eq("userId", ent.getUserId()));
        if (s == null) {
            return;
        }

        // TODO 增加返回 提示的代码
        OrderSeller os = orderSellerDao.findUnique(Restrictions.eq("orderId", vo.getOrderId()), Restrictions.eq("sellerId", s.getSellerId()));
        if (os == null) {
            return;
        }

        // 校验店家是否有这单
        OrderInfo oi = orderInfoDao.get(vo.getOrderId());
        if (oi == null) {
            return;
        }
        // 2: 为商家确认
        oi.setOrderStatus((short) 2);
        // 1: 已发货
        oi.setShippingStatus((short) 1);
        oi.setConfirmTime(new Timestamp(System.currentTimeMillis()));
        this.orderInfoDao.save(oi);
    }

    /**
     * 取当月店家订单数
     * @param sellerId
     * @return
     */
    public int getOrdersNumBySeller(Integer sellerId) {
        String sql = "SELECT COUNT(order_id) cnt FROM order_info oi WHERE oi.order_status=2 and oi.pay_status=1" +
                " and oi.seller_id=" + (sellerId == null ? 0 : sellerId);
        SQLQuery query = this.orderInfoDao.createSQLQuery(sql);
        String str = query.uniqueResult().toString();
        return Integer.parseInt(StringUtils.isBlank(str) ? "0" : str);
    }

    /**
     * 取当月某产品销量
     * @param goodsId
     * @return
     */
    public int getNumByGoods(Integer goodsId) {
        // 加上时间和订单状态
        String sql = "SELECT ifnull(SUM(g.goods_number),0) cnt FROM order_goods g JOIN order_info oi ON g.order_id=oi.order_id WHERE oi.order_status=2 and oi.pay_status=1 " +
                " and g.goods_id=" + (goodsId == null ? 0 : goodsId);
        SQLQuery query = this.orderInfoDao.createSQLQuery(sql);
        String str = query.uniqueResult().toString();
        return Integer.parseInt(StringUtils.isBlank(str) ? "0" : str);
    }

    /**
     * 取当月某产品销量
     * @param goodsIds
     * @return
     */
    public Map<Integer, Integer> getNumByGoodses(List<Integer> goodsIds) {
        Map<Integer, Integer> ret = new HashMap<Integer, Integer>();

        if (goodsIds == null || goodsIds.isEmpty()) {
            return ret;
        }

        StringBuffer sb = new StringBuffer();
        sb.append("(");
        boolean isFirst = true;
        for (Integer goodsId : goodsIds) {
            if (isFirst) {
                sb.append(goodsId);
                isFirst = false;
            } else {
                sb.append("," + goodsId);
            }
        }
        sb.append(")");

        // 加上时间和订单状态
        String sql = "SELECT g.goods_id, ifnull(SUM(g.goods_number),0) cnt FROM order_goods g JOIN order_info oi ON g.order_id=oi.order_id WHERE oi.order_status=2 and oi.pay_status=1 " +
                " and g.goods_id  in " + sb.toString() + " \n" +
                " GROUP BY g.goods_id";
        SQLQuery query = this.orderInfoDao.createSQLQuery(sql);
        List<Object[]> objs = (List<Object[]>) query.list();
        if (objs == null || objs.isEmpty()) {
            return ret;
        }

        for (Object[] obj : objs) {
            Integer key = Integer.parseInt(obj[0] == null ? "0" : obj[0].toString());
            Integer cnt = Integer.parseInt(obj[1] == null ? "0" : obj[1].toString());

            ret.put(key, cnt);
        }
        return ret;
    }

    @Transactional(readOnly = false)
    public void jobreceivingConfirmationSpeBySelf(JobReceivingOrderVO vo) {
        Timestamp[] days = getDay(vo.getDay());
        List<OrderInfo> ois = this.orderInfoDao.findbyorder("orderId", false,
                Restrictions.eq("payStatus", (short) 1), Restrictions.eq("orderStatus", (short) 2),
                Restrictions.eq("shippingStatus", (short) 1), Restrictions.isNull("receivingTime"),
                Restrictions.between("addTime", days[0], days[1]));
        for (OrderInfo oi : ois) {
            // 已收货
            oi.setShippingStatus((short) 2);
            oi.setReceivingTime(DateUtils.getSysTimestamp());
            this.orderInfoDao.save(oi);
        }
    }

    private Timestamp[] getDay(String asDay) {
        if (StringUtils.isBlank(asDay)) {
            return null;
        }

        String daystart = asDay.substring(0, 4) + "-" + asDay.substring(4, 6) + "-" + asDay.substring(6) + " 00:00:00";
        String dayend = asDay.substring(0, 4) + "-" + asDay.substring(4, 6) + "-" + asDay.substring(6) + " 23:59:59";
        Timestamp[] o = new Timestamp[2];

        o[0] = new Timestamp(DateUtils.parseDate(daystart).getTime());
        o[1] = new Timestamp(DateUtils.parseDate(dayend).getTime());
        return o;
    }
}
